/*************************************************************************
 *                                                                       *
 * This file is part of the FreeMAPs distribution.  For full copyright   *
 * information, see COPYRIGHT and COPYING.LESSER.                        *
 *                                                                       *
 * Author:           sqbang                                              *
 * Email:            sqbang@ustc.edu                                     *
 * Date:             2015.07.10                                          *
 * Description:      all regions info                                    *
 *                                                                       *
 *************************************************************************/

#ifndef FreeMAPs_include_COMMON_info_RegionInfo_h
#define FreeMAPs_include_COMMON_info_RegionInfo_h

#include "FreeMAPsConfig.h"

//COMMON headers
#include "COMMON/base/StateIndicator.h"


#include <map>


namespace FreeMAPs
{

//forward declaration
class Region;
class SimpleRegion;

/**
 * @brief RegionInfo manager all region_groups.
 *
 * the region is the base of the simulations,
 * all equation will be defined on some region_group.
 * each region group will be consists of several region.
 * each region may have several simple regions.
 * each simple region will have a unified material.
 * different regions may have same material.
 */
class RegionInfo : public StateIndicator
{
public:

    RegionInfo(
        const std::string& object_name);

    ~RegionInfo();

public:

    inline bool
    is_empty() const;

    inline bool
    has_region (
        const std::string& region_name) const;

    inline const std::map<std::string, Region*>&
    get_regions() const;

    inline const std::map<std::string, const SimpleRegion*>&
    get_simple_regions() const;


public:

    void
    clear();

    Region*
    get_region (
        const std::string& region_name);

    const SimpleRegion*
    get_simple_region (
        const std::string& simple_region_name) const;

    void
    get_from_input (
        const InputDatabase* db);

    friend std::ostream&
    operator << (
        std::ostream& os,
        const RegionInfo& rhs);

    void add_region(
            const std::string region_name,
            const std::map<std::string, std::string> map_simple_to_attr_name );

    bool
    check_all_info_db(const InputDatabase* db);


private:

    void
    insert_simple_regions (
        const InputDatabase* db,
        const Region* region);

private:

    typedef StateIndicator Parent;

    /*
     * map<region_name, region*>
     * different regions may overlap each other.
     */
    std::map<std::string, Region*> d_regions;

    /*
     * map<simple_region_name, simple_region*>
     * this is required because it is usually want to know an elem's attribute,
     * while the elem only know the simple region information(subdomain id)
     */
    std::map<std::string, const SimpleRegion*> d_simple_regions;

private:

    DISALLOW_COPY_AND_ASSIGN (RegionInfo);
};

} //namespace FreeMAPs

#include "COMMON/info/RegionInfo.inl"

#endif
